package example.fileuplaod2;

import grpc.htsoft.fileupload2.FileChunk;
import grpc.htsoft.fileupload2.FileUploadServiceGrpc;
import grpc.htsoft.fileupload2.UploadStatus;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;

import java.io.FileOutputStream;
import java.io.IOException;

public class FileUploadServer {


    private final int port = 50051;
    private final Server server;

    public FileUploadServer() {
        this.server = ServerBuilder.forPort(port)
                .addService(new FileUploadServiceImpl())
                .build();
    }

    public void start() throws IOException {
        server.start();
        System.out.println("Server started, listening on " + port);
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.err.println("*** shutting down gRPC server since JVM is shutting down");
            FileUploadServer.this.stop();
            System.err.println("*** server shut down");
        }));
    }

    public void stop() {
        if (server != null) {
            server.shutdown();
        }
    }

    public void blockUntilShutdown() throws InterruptedException {
        if (server != null) {
            server.awaitTermination();
        }
    }

    static class FileUploadServiceImpl extends FileUploadServiceGrpc.FileUploadServiceImplBase {
        @Override
        public StreamObserver<FileChunk> upload(StreamObserver<UploadStatus> responseObserver) {
            return new StreamObserver<FileChunk>() {
                FileOutputStream output;

                {
                    try {
                        output = new FileOutputStream("/Users/zgw/temp/a.png");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onNext(FileChunk value) {
                    try {
                        System.out.println("onNext server");

                        output.write(value.getContent().toByteArray());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onError(Throwable t) {
                    t.printStackTrace();
                }

                @Override
                public void onCompleted() {
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    responseObserver.onNext(UploadStatus.newBuilder().setSuccess(true).setMessage("File uploaded successfully").build());
                    responseObserver.onCompleted();
                }
            };
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        final FileUploadServer server = new FileUploadServer();
        server.start();
        server.blockUntilShutdown();
    }
}
